﻿using System;
using T0yK4T.Tools;
using T0yK4T.IO;
using System.Collections.Generic;

namespace ToyChat.Server
{
    /// <summary>
    /// Common interface for the server part of ToyChat
    /// </summary>
    public interface IServer : IDisposable
    {
        /// <summary>
        /// Adds the specified handler to the server's internal packet switch / queue
        /// </summary>
        /// <param name="handler">The handler that should be added</param>
        void AddHandler(IServerModule handler);

        /// <summary>
        /// Called from a <see cref="IUser"/> when it has disconnected
        /// </summary>
        /// <param name="user">The <see cref="IUserInfo"/> instance that represents the user that has disconnected</param>
        void OnDisconnect(IUser user);

        /// <summary>
        /// Called from a <see cref="IUser"/> whenever it has received a packet
        /// </summary>
        /// <param name="user">The <see cref="IUser"/> that received the packet</param>
        /// <param name="packet">The <see cref="Packet"/> that was received</param>
        void OnPacketReceived(IUser user, Packet packet);

        /// <summary>
        /// Starts the server (if it is not already started)
        /// </summary>
        void Start();

        /// <summary>
        /// Stops the server (if it is running)
        /// </summary>
        void Stop();

        /// <summary>
        /// Broadcasts the specified packet to all users that are currently connected
        /// </summary>
        /// <param name="packet">The packet to broadcast</param>
        void Broadcast(Packet packet);

        /// <summary>
        /// Gets the nametable that represents the current state of the internal TypeID to name map
        /// </summary>
        Dictionary<string, uint> IDMap { get; }

        /// <summary>
        /// Gets the "global" database handler currently in use
        /// </summary>
        IDatabaseHandler GlobalDBHandler { get; set; }

        /// <summary>
        /// Gets the settings that are currently in use by the server
        /// </summary>
        IServerSettings Settings { get; }

        /// <summary>
        /// Gets a reference to the userhandler currently in use by the server
        /// </summary>
        IUserHandler UserHandler { get; }

        /// <summary>
        /// Gets a reference to the channelhandler currently in use by the server
        /// </summary>
        IChannelHandler ChannelHandler { get; }

        /// <summary>
        /// This event should be fired whenever a new user has connected
        /// </summary>
        event UserEventHandler UserConnected;

        /// <summary>
        /// This even should be fired whenever a user has disconnected
        /// </summary>
        event UserEventHandler UserDisconnected;

        /// <summary>
        /// Gets the name of the server
        /// </summary>
        string Name { get; set; }

        /// <summary>
        /// This event should be fired when the informations of this server have changed (such as name or motd)
        /// </summary>
        event Action ServerInfoChanged;

        /// <summary>
        /// Gets the MotD of the server
        /// </summary>
        string MotD { get; set; }

        /// <summary>
        /// Checks the specified user for the specified permission flags
        /// </summary>
        /// <param name="user">The user to check</param>
        /// <param name="flags">The flags to check for</param>
        /// <returns>True if the specified flags are defined in the user's permissions, otherwise false</returns>
        bool CheckPermissions(IUser user, PermissionFlags flags);
    }
}
